package edzest.basic;

public class J16_Calculator {

	public static void main(String[] args) {
		// 상속, 인터페이스, 기본클래스를 이용해서
		// 사칙연산을 수행하는 계산기 프로그램 작성
		J16Add add = new J16Add();
		add.setValue(3, 7);
		System.out.println( add.toString() );
		System.out.println( add.calculate() );
		
		J16Mul mul = new J16Mul();
		// add.setValue(3, 7); -> mul.calculate()값 0나옴
		// x,y 의 기본값 0인거
		mul.setValue(3, 7);
		System.out.println( mul.toString() );
		System.out.println( mul.calculate() );
		// 위는 더하기, 곱셈하려고 J16Add, J16Mul 객체 2번 생성. 메모리 낭비
		// 하지만 -, / 연산을 위해
		// J16Sub, J16Div 객체도 생성해야 함
		// 사칙연산을 위해 불필요한 객체를 
		// 마구 생성하는 낭비가 발생
		// 해결책 - 상위 자료형변환upcasting을 이용
		// upcasting: 서브클래스의 자료형을 부모클래스로
		
		// 아래는 객체 c 하나로 더하기, 곱셈 실행. 메모리 절약
		J16Cal c = new J16Add();
		c.setValue(10, 100);
		System.out.println(c.toString());
		System.out.println(c.calculate());
		
		c = new J16Mul();
		c.setValue(150, 25);
		System.out.println(c.toString());
		System.out.println(c.calculate());
		// +, x 연산을 위해 J16Add, J16Mul의
		// 부모인 J16Cal 객체만 생성
		// 추후 -, / 연산을 위해
		// J16Sub, J16Div 객체를 생성하더라도
		// 부모인 J16Cal 객체만 가져다 쓰면 됨
	}

}

// 인터페이스
interface J16CalService {
	void setValue( int x, int y );
	int calculate();
}

// 인터페이스 구현한 기본클래스 작성
class J16Cal implements J16CalService {
	private int x; 
	// 초기값 0, 곱셈에서 setValue로 설정안하니까 결과가 0뜸
	private int y;
	
	public J16Cal() {}
	
//  멤버변수 x, y 의 초기화 작업은
//  setValue 메서드가 대신하므로
//  생성자는 주석처리함
//	public J16Cal(int x, int y) {
//		this.x = x;
//		this.y = y;
//	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	@Override
	public String toString() {
		return "J16Cal [x=" + x + ", y=" + y + "]";
	}

	@Override
	public void setValue(int x, int y) {
		this.x = x;
		this.y = y;
		// this(x, y);
		// Constructor call must be the first statement in a constructor
	}

	@Override
	public int calculate() {
		return 0;
	}
	
}

class J16Add extends J16Cal {
	@Override
	public int calculate() {
		// return x + y;
		// The field J16Cal.y is not visible
		return getX() + getY();
	}
}

class J16Mul extends J16Cal {
	@Override
	public int calculate() {
		return getX() * getY();
	}
}